package org.stvd.core.exception;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import org.stvd.core.process.ReportBugThread;
import org.stvd.core.util.DateUtil;
import org.stvd.core.web.IOUtil;
import org.stvd.core.web.IPUtil;

public class HandlerExceptionResolverEx implements HandlerExceptionResolver {

    private static Logger logger = Logger.getLogger(HandlerExceptionResolverEx.class);

    private String errorPage = "/common/exception.html";
    // 是否发送邮件
    private boolean sendEmail = false;
    // 主题
    private String subject = "";
    // 邮件列表 {"fddev@5starsoft.com.cn","szhf@5starsoft.com.cn"}
    String[] address = { "fddev@5starsoft.com.cn" };

    public String getErrorPage() {
        return errorPage;
    }

    public void setErrorPage(String errorPage) {
        this.errorPage = errorPage;
    }

    public boolean isSendEmail() {
        return sendEmail;
    }

    public void setSendEmail(boolean sendEmail) {
        this.sendEmail = sendEmail;
    }

    public String getSubject() {
        if (subject != null && !"".equals(subject)) {
            return subject;
        } else {
            return "Exception:" + DateUtil.getSystemDateOfString();
        }
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    public String[] getAddress() {
        return address;
    }

    public void setAddress(String[] address) {
        if (address != null) {
            this.address = Arrays.copyOf(address, address.length);
        }
    }

    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
            Exception ex) {
        logger.error("Catch Exception: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>", ex);
        Map<String, Object> map = new HashMap<String, Object>();

        ExceptionPrintWriter strintPrintWriter = new ExceptionPrintWriter();
        ex.printStackTrace(strintPrintWriter);

        String error = strintPrintWriter.getString();
        // String errorMsg = "";
        // try {
        // errorMsg = error.substring(error.indexOf(": ") + 1,
        // (error.indexOf("\r\n") == -1) ? error.indexOf("at") : error.indexOf("\r\n"));
        // } catch (Exception e) {
        // errorMsg = error;
        // }

        // 请求地址
        String errorURL = "[" + request.getMethod() + "]" + request.getRequestURL();
        if (request.getQueryString() != null && !"".equals(request.getQueryString())) {
            try {
                errorURL += "?" + new String(request.getQueryString().getBytes("ISO-8859-1"), "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }

        // 获取IP地址
        String[] ipArray = IPUtil.getIpAddrArray(request);
        StringBuilder ipResult = new StringBuilder();
        if (ipArray != null && (ipArray.length > 0)) {
            for (String ip : ipArray) {
                ipResult.append(ip).append('(');
                String[] areaArray = null;
                try {
                    areaArray = IPUtil.find(ip);
                    if (areaArray != null && (areaArray.length > 0)) {
                        for (String area : areaArray) {
                            if (!"".equals(area)) {
                                ipResult.append(area);
                            }
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                ipResult.append(");");
            }
        }

        try {
            error = DateUtil.Y2DTIME_FORMAT.format(DateUtil.getSystemDate()) + ":\r\n" + "\t" + ipResult.toString()
                    + "\r\n" + "\t" + errorURL + "\r\n" + error;

            // 增加异常日志文件
            String dateStr = DateUtil.Y2D_FORMAT.format(DateUtil.getSystemDate());
            String fileName = "error.txt";
            String filePath = request.getSession().getServletContext().getRealPath("/") + "/errorMsg/" + dateStr + "/";
            IOUtil.saveFile(filePath, fileName, error, true);

            // 邮件报送bug消息
            if (sendEmail) {
                (new ReportBugThread(subject, error, address)).start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        map.put("errorURL", errorURL);
        map.put("errorMsg", error);

        return new ModelAndView(errorPage, map);
    }

}
